package com.bonana.core.utils;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;

import com.bonana.utils.DateTool;
import com.bonana.utils.StringUtils;
import com.bonana.utils.SystemConfig;
import com.google.common.io.Closer;
import org.apache.commons.io.IOUtils;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import javax.imageio.stream.MemoryCacheImageInputStream;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.UUID;

/**
 * Created by justin on 15/8/17.
 */
public class OssUtils {
    private static final String ACCESS_KEY_ID = SystemConfig.getString("oss.accessKeyId");
    private static final String ACCESS_KEY_SECRET = SystemConfig.getString("oss.accessKeySecret");
    private static final String ENDPOINT = SystemConfig.getString("oss.endpoint");
    private static final String BUCKET_NAME = SystemConfig.getString("oss.bucketName");
    private static final String RES_ULR = SystemConfig.getString("oss.resUrl");

    private static Map<String, String> miniType = new HashMap<String,String>();

    static {
        miniType.put("txt", "text/plain");
        miniType.put("html", "text/html");
        miniType.put("xml", "application/xml");
        miniType.put("gif", "image/gif");
        miniType.put("jpg", "image/jpeg");
        miniType.put("jpeg", "image/jpeg");
        miniType.put("png", "image/png");
        miniType.put("mpeg", "video/mpeg");
        miniType.put("pdf", "application/pdf");
        miniType.put("doc", "application/msword");
        miniType.put("", "image/png");
    }

    public static String getMineType(String suffix) {
        if (miniType.containsKey(suffix)) {
            return miniType.get(suffix);
        } else {
            throw new RuntimeException("error suffix");
        }
    }

    public static String getSuffixByFilename(String filename) {
        String extName = "";
        if (filename != null) {
            if ((filename != null) && (filename.indexOf(".") != -1)) {
                extName = filename.substring(filename.lastIndexOf(".") + 1);
            }
        }
        return extName.toLowerCase();
    }

    public static String putFileRetUrl(MultipartFile avatarFile) {
        return putFile(avatarFile).getUrl();
    }

    public static FileInfo putFile(MultipartFile avatarFile) {
        String suffix = OssUtils.getSuffixByFilename(avatarFile.getOriginalFilename());
        try {
            return OssUtils.putFile(avatarFile.getInputStream(), suffix);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("upload file error", e);
        }
    }

    private static ImageInputStream createImageInputStream(InputStream is) throws IOException {
        return new MemoryCacheImageInputStream(is);
    }

    public static BufferedImage readImage(InputStream inputStream, String contentType) throws IOException {
        ImageInputStream imageInputStream = null;
        ImageReader imageReader = null;
        try {
            imageInputStream = createImageInputStream(inputStream);
            //MediaType mediaType = inputMessage.getHeaders().getContentType();
            //Iterator<ImageReader> imageReaders = ImageIO.getImageReadersBySuffix(suffix);

            Iterator<ImageReader> imageReaders = ImageIO.getImageReadersByMIMEType(contentType);
            if (imageReaders.hasNext()) {
                imageReader = imageReaders.next();
                ImageReadParam irp = imageReader.getDefaultReadParam();
                imageReader.setInput(imageInputStream, true);
                return imageReader.read(0, irp);
            } else {
                throw new HttpMessageNotReadableException("Could not find javax.imageio.ImageReader for  [" + contentType + "]");
            }
        } finally {
            if (imageReader != null) {
                imageReader.dispose();
            }
            if (imageInputStream != null) {
                try {
                    imageInputStream.close();
                } catch (IOException ex) {
                    // ignore
                }
            }
        }
    }


    public static FileInfo uploadImage(MultipartFile file) {
        String suffix = OssUtils.getSuffixByFilename(file.getOriginalFilename());
        try {
            return OssUtils.putFile(file.getInputStream(), suffix);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException("upload file error", e);
        }
    }

    public static FileInfo uploadImage(InputStream inputStream, String suffix) {
        Closer closer = Closer.create();

        // 初始化一个OSSClient
        OSSClient client = new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        String miniType = getMineType(suffix);
        // 创建上传Object的Metadata
        ObjectMetadata meta = new ObjectMetadata();
        meta.setContentType(miniType);
        // 必须设置ContentLength
        try {
            meta.setContentLength(inputStream.available());
        } catch (IOException e) {
            e.printStackTrace();
        }
        FileInfo fileInfo = new FileInfo();

        ByteArrayOutputStream buffer = closer.register(new ByteArrayOutputStream());
        try {
            IOUtils.copy(inputStream , buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String realPath = DateTool.getNow("yyyyMMdd") + "/" + UUID.randomUUID().toString().replaceAll("-", "");
        if (StringUtils.hasText(suffix)) {
            realPath += "." + suffix;
        }
        try {
            // 上传Object.
            PutObjectResult result = client.putObject(BUCKET_NAME, realPath, closer.register(new ByteArrayInputStream(buffer.toByteArray())), meta);
            // 打印ETag
            System.out.println(result.getETag());
            fileInfo.setUrl(RES_ULR + "/" + realPath);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (suffix.equalsIgnoreCase("jpg") || suffix.equalsIgnoreCase("jpeg") || suffix.equalsIgnoreCase("gif")
                || suffix.equalsIgnoreCase("bmp") || suffix.equalsIgnoreCase("png")) {

            try {
                ImageInputStream iis = ImageIO.createImageInputStream(closer.register(new ByteArrayInputStream(buffer.toByteArray())));
                Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);

                if (readers.hasNext()) {
                    //Get the first available ImageReader
                    ImageReader reader = readers.next();
                    reader.setInput(iis, true);

                    fileInfo.setH(reader.getHeight(0));
                    fileInfo.setW(reader.getWidth(0));
                }

                iis.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {


            }
        }

        try {
            closer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileInfo;
    }


    public static FileInfo putFile(InputStream inputStream, String suffix) {
        // 初始化一个OSSClient
        OSSClient client = new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        String miniType = getMineType(suffix);
        // 创建上传Object的Metadata
        ObjectMetadata meta = new ObjectMetadata();
        meta.setContentType(miniType);
        // 必须设置ContentLength
        try {
            meta.setContentLength(inputStream.available());
        } catch (IOException e) {
            e.printStackTrace();
        }
        FileInfo fileInfo = new FileInfo();
        Closer closer = Closer.create();

        ByteArrayOutputStream buffer = closer.register(new ByteArrayOutputStream());
        try {
            IOUtils.copy(inputStream , buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String realPath = DateTool.getNow("yyyyMMdd") + "/" + UUID.randomUUID().toString().replaceAll("-", "");
        if (StringUtils.hasText(suffix)) {
            realPath += "." + suffix;
        }
        try {
            // 上传Object.
            PutObjectResult result = client.putObject(BUCKET_NAME, realPath, closer.register(new ByteArrayInputStream(buffer.toByteArray())), meta);
            // 打印ETag
            System.out.println(result.getETag());
            fileInfo.setUrl(RES_ULR + "/" + realPath);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (suffix.equalsIgnoreCase("jpg") || suffix.equalsIgnoreCase("jpeg") || suffix.equalsIgnoreCase("gif")
                || suffix.equalsIgnoreCase("bmp") || suffix.equalsIgnoreCase("png")) {

            try {
                ImageInputStream iis = ImageIO.createImageInputStream(closer.register(new ByteArrayInputStream(buffer.toByteArray())));
                Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);

                if (readers.hasNext()) {
                    //Get the first available ImageReader
                    ImageReader reader = readers.next();
                    reader.setInput(iis, true);

                    fileInfo.setH(reader.getHeight(0));
                    fileInfo.setW(reader.getWidth(0));
                }

                iis.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {


            }
        }

        try {
            closer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return fileInfo;
    }


    public static void main(String[] args) {

    }
}
